package com.example.xunai.repository;

import com.example.xunai.entity.TokenUsage;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.time.LocalDate;
import java.util.List;
import java.util.Map;

@Repository
public interface TokenUsageRepository extends JpaRepository<TokenUsage, Long> {

    /**
     * 按模型统计用户token使用量
     */
    @Query("SELECT " +
            "tu.model as model, " +
            "SUM(tu.inputTokens) as totalInputTokens, " +
            "SUM(tu.outputTokens) as totalOutputTokens, " +
            "SUM(tu.inputTokens + tu.outputTokens) as totalTokens, " +
            "COUNT(tu.id) as usageCount " +
            "FROM TokenUsage tu " +
            "WHERE tu.userId = :userId " +
            "AND DATE(tu.usageDate) BETWEEN :startDate AND :endDate " +
            "GROUP BY tu.model")
    List<Map<String, Object>> getUserTokenStatsByModel(@Param("userId") Long userId,
                                                       @Param("startDate") LocalDate startDate,
                                                       @Param("endDate") LocalDate endDate);

    /**
     * 用户每日token使用趋势
     */
    @Query("SELECT " +
            "DATE(tu.usageDate) as usageDate, " +
            "SUM(tu.inputTokens + tu.outputTokens) as dailyTokens, " +
            "SUM(tu.inputTokens) as dailyInputTokens, " +
            "SUM(tu.outputTokens) as dailyOutputTokens " +
            "FROM TokenUsage tu " +
            "WHERE tu.userId = :userId " +
            "AND DATE(tu.usageDate) BETWEEN :startDate AND :endDate " +
            "GROUP BY DATE(tu.usageDate) " +
            "ORDER BY DATE(tu.usageDate)")
    List<Map<String, Object>> getUserDailyTokenTrend(@Param("userId") Long userId,
                                                     @Param("startDate") LocalDate startDate,
                                                     @Param("endDate") LocalDate endDate);

    /**
     * 模型使用统计
     */
    @Query("SELECT " +
            "tu.model as model, " +
            "COUNT(DISTINCT tu.userId) as userCount, " +
            "COUNT(tu.id) as usageCount, " +
            "SUM(tu.inputTokens) as totalInputTokens, " +
            "SUM(tu.outputTokens) as totalOutputTokens, " +
            "SUM(tu.inputTokens + tu.outputTokens) as totalTokens, " +
            "AVG(tu.inputTokens + tu.outputTokens) as avgTokensPerRequest " +
            "FROM TokenUsage tu " +
            "WHERE DATE(tu.usageDate) BETWEEN :startDate AND :endDate " +
            "GROUP BY tu.model " +
            "ORDER BY totalTokens DESC")
    List<Map<String, Object>> getModelUsageStats(@Param("startDate") LocalDate startDate,
                                                 @Param("endDate") LocalDate endDate);

    /**
     * 获取用户最近使用的模型列表
     */
    @Query("SELECT DISTINCT tu.model FROM TokenUsage tu " +
            "WHERE tu.userId = :userId " +
            "ORDER BY MAX(tu.usageDate) DESC")
    List<String> findRecentModelsByUserId(@Param("userId") Long userId);

    /**
     * 获取对话的token使用详情
     */
    List<TokenUsage> findByConversationIdOrderByUsageDateDesc(@Param("conversationId") Long conversationId);

    /**
     * 获取用户指定时间段的token使用记录
     */
    List<TokenUsage> findByUserIdAndUsageDateBetween(@Param("userId") Long userId,
                                                     @Param("startDate") LocalDate startDate,
                                                     @Param("endDate") LocalDate endDate);

    /**
     * 统计用户总数
     */
    @Query("SELECT COUNT(DISTINCT tu.userId) FROM TokenUsage tu " +
            "WHERE DATE(tu.usageDate) BETWEEN :startDate AND :endDate")
    Long countDistinctUsersByDateRange(@Param("startDate") LocalDate startDate,
                                       @Param("endDate") LocalDate endDate);

    /**
     * 统计对话总数
     */
    @Query("SELECT COUNT(DISTINCT tu.conversationId) FROM TokenUsage tu " +
            "WHERE DATE(tu.usageDate) BETWEEN :startDate AND :endDate")
    Long countDistinctConversationsByDateRange(@Param("startDate") LocalDate startDate,
                                               @Param("endDate") LocalDate endDate);
}